#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2024/9/19 9:27
# @Author  : Tom_zc
# @FileName: prepare-env.py
# @Software: PyCharm
import json
import os
import shutil
import sys
import logging
import click

from pathlib import Path
from urllib.parse import urlparse

CURR_DIR = Path(__file__).resolve()
ROOT_DIR = CURR_DIR.parent.parent.parent
sys.path.append(ROOT_DIR.as_posix())

from scripts.utils.common import execute_cmd3
from scripts.utils.parse_params import parse_repo_info_by_webhook_payload

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s  %(levelname)s:%(message)s")


class PrePareEnv:
    clone_cmd = "git clone https://{}/{}/{}.git {}"
    checkout_branch_cmd = "git checkout {}"
    pull_cmd = "git pull"
    fetch_cmd = "git fetch origin refs/merge-requests/{n}/head:pr_{n}"
    checkout_cmd = "git checkout -b working_pr_{n}"
    merge_cmd = "git merge --no-edit pr_{n}"

    def prepare_env(self, owner, repo, pull_id, local_path,
                    branch="main", gitcode_domain=os.getenv("gitcode_domain")):
        """
        prepare local repo base and PR branch, And merge it
        """
        if os.path.exists(local_path):
            logging.info("WARNING: %s already exist, delete it." % local_path)
            shutil.rmtree(local_path)
        domain = urlparse(gitcode_domain)
        clone_cmd = self.clone_cmd.format(domain.netloc, owner, repo, local_path)
        ret, out, err = execute_cmd3(clone_cmd)
        if ret != 0:
            logging.info("Error: Failed to git clone {}, err:{}, out:{}".format("{}/{}".format(owner, repo), err, out))
            return 1
        os.chdir(local_path)
        ret, _, _ = execute_cmd3(self.checkout_branch_cmd.format(branch))
        if ret != 0:
            logging.info("Error: Failed to checkout %s branch" % branch)
            return 1
        ret, _, _ = execute_cmd3(self.pull_cmd)
        if ret != 0:
            logging.info("Error: Failed to update to latest commit in %s branch" % branch)
            return 1
        ret, _, _ = execute_cmd3(self.fetch_cmd.format(owner=owner, repo=repo, n=pull_id))
        if ret != 0:
            logging.info("Error:Failed to fetch PR:{n}".format(n=pull_id))
            return 1
        ret, _, _ = execute_cmd3(self.checkout_cmd.format(n=pull_id))
        if ret != 0:
            logging.info("Error:Failed to create working branch working_pr_{n}".format(n=pull_id))
            return 1
        ret, _, _ = execute_cmd3(self.merge_cmd.format(n=pull_id))
        if ret != 0:
            logging.info("Error:Failed to merge PR:{n} to branch:{base}".format(n=pull_id, base=branch))
            return 1
        return 0


@click.command()
@click.option("--gitcode_domain", help='The gitcode domain')
@click.option("--code_path", help='The code repo path', default='')
def main(gitcode_domain, code_path):
    """clone the repo and pull the pr and merge it"""
    logging.info("=" * 20 + "start to prepare env" + "=" * 20)
    if not gitcode_domain:
        logging.info("Lack of params, Please check.")
        sys.exit(-1)

    owner, repo, branch, pr_number, _ = parse_repo_info_by_webhook_payload()
    logging.info("Receive the request from {}/{}/{}/{}".format(owner, repo, branch, pr_number))
    with open(".config", "w") as fp:
        fp.write(repo)

    result = PrePareEnv().prepare_env(owner, repo, pr_number, code_path or repo,
                                      branch=branch, gitcode_domain=gitcode_domain)
    if result != 0:
        logging.info("Error: prepare env failed")
        sys.exit(-1)
    result = {
        "package": repo
    }
    print(json.dumps(result))
    logging.info("=" * 20 + "end to prepare env" + "=" * 20)
    sys.exit(0)


if __name__ == '__main__':
    main()
